\chapter{Diseño del Sistema}

\section{Introducción}
	Desde el comienzo se encaró una metodología de desarrollo organizada y escalada para abarcar cada uno de los requerimientos funcionales planteados.
	El diseño fue indispensable para permitirnos distinguir cada parte del sistema, sus funcionalidades y las tecnologías asociadas, haciendo que el planteo de la solución sea mas claro y el proceso de codificación más natural.
	Este capitulo explica las distintas etapas de diseño. Comenzando por el Diseño de Arquitectura donde se da una descripción detallada del sistema obtenido a través del análisis de sus partes. Continuando con el diseño de Alto nivel explicado a través del Diagrama de Paquetes. Además, se explica como los requerimientos funcionales influenciaron en las decisiones tomadas durante el proceso de diseño.\\
	
 Vale aclarar que estas especificaciones se encuentran también disponibles en el documento de diseño estándar que anexamos al presente trabajo.

\section{Decisiones de Diseño}
En esta sección damos una explicación detallada de las decisiones de diseño, cómo derivan de los requerimientos funcionales, de los principios de diseño (SOLID) y del uso de patrones de diseño.

\paragraph{Forma de modelado del diseño}
Al momento de elegir la forma de modelado se optó el diseño orientado a responsabilidades (Responsibility-driven design), debido a era más fácil encarar el problema desde el punto de vista de las responsabilidades, en lugar de hacerlo a partir de los datos involucrados (debido a su cantidad y complejidad). Además, permite cumplir con los principios de SOLID de manera simple.

\paragraph{Flujo de datos basado en observadores}
Del requerimiento RF12 se desprende la necesidad de manejar los datos de forma diferente. O sea, no esperar a que un bloque de datos sea generado completamente para procesarlo, si no hacerlo a medida que se genera cada dato. Para lograrlo se pensó las siguientes alternativas. 
\begin{itemize}
\item Hacer que cada módulo acceda a los datos y los procese cuando los necesite. Esta opción concuerda con el patrón $Visitor$.
\item Hacer que los módulos avisen cuando generan un nuevo dato y los módulos dependientes de estos actualicen su estado con el dato nuevo. Esta otra opción concuerda con patrón $Observer$.
\end{itemize}
Por la naturaleza del problema y dado que es más probable que el módulo encargado de generar los datos haga esperar al modulo que los requiere, se opto por la segunda opción.
Se adapto el diseño del sistema para que todo el flujo de datos, desde la entrada de parámetros hasta la salida del las terapias contenidas en el $Ranker$, se base en el patrón $Observador$ (Cadena de observadores).\\

\paragraph{Incorporación de un plugin}
Las pautas de tratamiento del VIH varían mucho de un profesional a otro y son muy pocos los acuerdos a nivel mundial sobre este tema. Por lo cual un sistema que se apegue a un grupo de pautas fijas resultaría en un trabajo limitado. La decisión de incorporar un plugin al sistema surge como respuesta a la necesidad de adaptación de este a distintos usuarios.\\

Por otro lado, el administrador de plugins hace un extenso uso del patrón $Adapter$ en su labor de adaptar las interfaces del plugin a las del sistema.\\

Vale la pena denotar que el uso de un plugin y del administrador de plugins, como nexo entre este y el sistema, es un claro ejemplo de OCP.

\paragraph{Plantilla $Ranker$}
Originariamente se pensó el objeto $Ranker$ como un contenedor de terapias que solo contiene las $N$ mejores de acuerdo a algún valor. Sin embargo, se notó que un objeto con esta capacidad podía ser de mucha utilidad a lo largo de todo el proyecto, inclusive en otros. Se optó por crear una plantilla $Ranker$ basándose en el patrón $Template Method$.
Vale la pena mencionar que esta librería fue incorporada a Mili (Minimalistic Libraries de C++).

\paragraph{Plantilla $VariantSet$}
Al momento de diseñar como el plugin pediría los parámetros necesarios al usuario, nos encontramos con el inconveniente de lidiar con los tipos variables de estos. Para solucionarlo se pensaron varias posibilidades, entre ellas: hacer uso de $boost::any$, $boost::variant$, implementar un contenedor capaz de almacenar cualquier tipos de datos o incurrir en punteros nulos.(Boost: es un conjunto de bibliotecas de software libre y revisión por pares preparadas para extender las capacidades del lenguaje de programación C++  \url{http://www.boost.org}).\\

Se decidió descartar el uso de $any$ y $variant$ de boost, ya que incorporar boost al sistema implicaría un aumento importante en la complejidad de este. O sea, no valía el esfuerzo incorporarla al sistema sólo para el uso de estas variables.
Se optó por construir un contenedor, que a partir de herramientas del lenguaje, almacene cualquier tipo de datos. Para construirlo se utilizó el patrón $Template Method$, así los métodos de inserción y remoción no dependerán de un tipo especifico.
Esta plantilla también fue incorporada a Mili, para su uso en otros proyectos.
 

\section{Diseño de Arquitectura}

	Esta etapa de diseño plantea al sistema como un conjunto de componentes y conectores que denotan las tecnologías y partes involucradas en el mismo.
	
\begin{figure}[ht]
\centering
\includegraphics[width=\linewidth]{pictures/Arquitectura.jpeg}
\caption{Arquitectura del sistema.} 
\end{figure} 

\subsection{Fundamentación de la Arquitectura}
Este diseño divide el sistema en cuatro grandes partes: el plugin, las librerías externas, la base de datos y el núcleo del sistema. De esta forma, se separa el núcleo de todo aquello que resulta ajeno al proceso de generación. Logrando un sistema compacto (apegado a OCP), robusto y modular que garantiza poco acoplamiento.
Es decir, el conjunto de elementos de calculo y valores que pueden variar de acuerdo a un usuario particular, se enmarcan dentro del $Plugin$ y $Antiviral Data Base$. Permitiendo que el sistema propiamente dicho permanezca invariable ante futuras modificaciones.


\subsection{Catálogo de Componentes}

\begin{itemize}
\item \textbf{System:} Aplicación principal que enmarca los siguientes componentes.

\begin{itemize}
\item \textbf{Main Program:} componente principal del sistema, que coordina las distintas partes para la ejecución. Sus funciones son comunicarse con la interfaz gráfica $GUI$ para pedir y mostrar datos, cargar la base de datos $Antiviral Data Base$, solicitar la carga de un plugin a través del $Plugin Administrator$, ejecutar la generación del espacio de búsqueda $Therapy Generator$ y la posterior selección de las mejores terapias $Therapy Ranker$.

\item \textbf{GUI:}Interfaz gráfica, su función es hacer más simple la interacción entre el usuario y el sistema.

\item \textbf{Plugin Administrator:} componente encargado de cargar y descargar los plugins, haciendo los respectivos chequeos de consistencia con el sistema.

\item \textbf{Therapy Generator:} se encargado de generar el espacio de búsqueda de terapias, tomando en cuenta las modificaciones incorporadas a través del $Plugin Administrator$.

\item \textbf{Combinatory Engine:} motor de combinación de antirretrovirales. Su función es generar combinaciones antirretrovirales de acuerdo a los requerimientos del plugin. Esta presente en varios componentes ($Plugin$, $Therapy Generator$, $libplugin$).
En el cap. 7 se hace una descripción detallada del mismo.
 	
\item \textbf{Antivirals Selector:} componente encargado establecer los conjuntos de antivirales aplicables a una secuencia nucleotídica.

\item \textbf{Ranker:} componente encargado de generar una lista ordenada, con las $N$ terapias de mayor puntaje, ponderadas de acuerdo a los parámetros establecidos por el usuario.

\end{itemize}

\item \textbf{Libplugin:} Conjunto de herramientas y librerías (SDK) para la construcción de plugins.

\item \textbf{Plugin:} modulo independiente que se acopla al sistema para aumentar o modificar su funcionalidad. El cual provee algoritmos, políticas y datos en tiempo de ejecución.

\item \textbf{Qt:} Framework de desarrollo para interfaces gráficas.(\url{http://nokia.qt.com})

\item \textbf{BIOpp:} Biblioteca para manipulación de cadenas de aminoácidos/proteínas.(\url{http://biopp.googlecode.com})

\item \textbf{Mili:} Biblioteca de soporte para simplificar el uso del lenguaje de implementación (C++).(\url{http://mili.googlecode.com})

\item \textbf{Antiviral Data Base:} Almacenamiento de datos asociados a antirretrovirales. En este caso es indiferente el tipo de Base de Datos utilizada, solo interesa el acceso a su contenido. En particular se almacenan los datos de antirretrovirales en un archivo XML. Este componente se comunica con el sistema a través de FXP.
En el capitulo 11 se hace una descripción detallada del mismo.
\end{itemize}

\subsection{Descripción del Funcionamiento}
Como se ve en la Fig. 5.1 el sistema necesita de elementos externos. Primero, toma la base de datos ($Antiviral Data Base$) que contiene los antivirales. Luego, incorpora las funcionalidades del $Plugin$ proporcionado por el usuario por medio del $Plugin Administrator$. A continuación, se solicitan los parámetros requeridos por el $Plugin$ y la secuencia nucleotídica del virus a través de la $GUI$. El generador de terapias  $Therapy Generator$ toma la secuencia y pregunta a $Antiviral Selector$ el subconjunto de antivirales que son efectivos contra el virus. Luego Genera las terapias y a medida que son generadas $Therapy Ranker$ las somete a un ranking de acuerdo a su valoración. Finalmente, se entrega al usuario las $N$ mejores terapias a través de la $GUI$. \\


\section{Diagrama de Paquetes}
El diagrama de paquetes muestra una perspectiva más detallada del sistema y provee una forma fácil y modular de introducirse al diseño de alto nivel.

\begin{figure}[ht]
\centering
\includegraphics[scale=0.7]{pictures/DiagramaPaquetesFinal.jpeg}
\caption{Diagrama de Paquetes.} 
\end{figure}

\afterpage{\clearpage}
A continuación se detalla cada paquete describiendo las clases que lo componen.

\subsection{Miscellaneous}
El paquete Miscellaneous contiene clases que se usan en varios paquetes.

\begin{figure}[ht]
\centering
\includegraphics[scale=0.7]{pictures/PackageMis.jpeg}
\caption{Paquete Miscellaneous.} 
\end{figure}


\begin{itemize}
\item\textbf{Observer} provee una interfaz usada a lo largo de todo el sistema y responde al requerimiento funcional RF12. Donde se propone la utilización de un diseño basado en Observers para mejorar la eficiencia del sistema.
\item\textbf{Ranker} otro de los elementos necesarios para organizar las terapias es el Ranker. Utilizamos esta clase genérica que permite la reutilización y que fue agregada a la librería Mili.
\end{itemize}

%---------------------------------------------------------------------------------------------

\subsection{DataBase}
Este paquete se desprende del RF2 establecido en el capitulo 3.

\begin{figure}[ht]
\centering
\includegraphics[scale=0.7]{pictures/PackageBD.jpeg}
\caption{Paquete Data Base.} 
\end{figure}

\begin{itemize}
\item\textbf{DataBase} la clase DataBase engloba el concepto de la base de datos de antirretrovirales y todas las funcionalidades asociadas, como por ejemplo, poder cargar un archivo XML, desabilitar elementos, etc. 
\end{itemize}

%---------------------------------------------------------------------------------------------------------------

\subsection{Antivirals}
La representación de antirretrovirales es central en este trabajo ya que son los elementos con los cuales el sistema realizará sus cálculos. En el capítulo 6 se hace una descripción detallada de los antirretrovirales y los algoritmos asociados.

\begin{figure}[ht]
\centering
\includegraphics[scale=0.7]{pictures/PackageAv.jpeg}
\caption{Paquete Antiviral.} 
\end{figure}

\begin{itemize}
\item\textbf{NucSequence} esta clase proviene de BIOpp y representa a una secuencia de Nucleótidos con varios métodos asociados para su manejo. Se representa como una cadena de cuatro posibles caracteres (A C G T).
\item\textbf{SequenceSet} con este tipo de dato definimos a un conjunto de secuencias nucleotídicas.
\item\textbf{MutantDist} cuando un antirretroviral aplica lo hace con una distancia genética determinada. Consideramos para este diseño el tomar la menor de las distancias. La clase MutantDist encierra al conjunto de mutantes y al valor mínimo que se consideró.
\item\textbf{DistanceMatrix} la matriz de distancias genéticas define al valor entre dos nucleótidos. Esta implentación deriva de BIOpp.
\item\textbf{Antiviral} clase que provee la interfaz de Antiviral. Esta define un conjunto de funcionalidades básicas de un antirretroviral y utiliza alguna implementacion determinada de este.
\item\textbf{ResistancePosition}  esta es una clase que define a una posición de resistencia en particular.
\item\textbf{ResisBasedAntiviral} es la implementacion de un Antirretroviral basado en posiciones de resistencia. Puede ocurrir que la interfaz utilice otra representación para los antirretrovirales. Ver capitulo 6.
\item\textbf{AntiviralSet} describe un conjunto de Antirretrovirales y operaciones para este.
\item\textbf{Mutant} es un tipo de dato que contiene información de una Mutante representada como 	
\item\textbf{AntiviralSelector} uno de los mecanismos que utiliza el sistema es el de poder seleccionar un conjunto de antirretrovirales que aplican a una secuencia. Esta clase provee esta funcionalidad colocando en un AntiviralSet los antirretrovirales que cumplen con esto. Esto responde al requerimiento funcional RF3.
\end{itemize}

%---------------------------------------------------------------------------------------------------------------

\begin{figure}[ht]
\centering
\includegraphics[scale=0.7]{pictures/PackageTh.jpeg}
\caption{Paquete Therapy.} 
\end{figure}

\subsection{Therapy}
Este paquete contiene las clases asociadas al concepto de terapias y responde a los requerimientos RF5.6 y RF5.7.

\begin{itemize}
\item\textbf{Info} contiene información relacionada a un $TherapyNode$, por ejemplo porque se asigno un determinado puntaje, efectos adversos de la combinación de antirretrovirales o particularidades de la mutante. Esta información se usa posteriormente para fundamentar y brindar información adicional sobre las terapias seleccionadas por el ranking. El implementador de plugin puede incorporar a esta clase toda la información que crea necesaria (RF5.6)\\

\item\textbf{TherapyNode} representa un nodo del árbol de generación, contiene la información necesaria para el calculo de mutantes, combinación de antirretrovirales, secuencia nucleotidica, algoritmo combinatorio a utilizar (RF5.7) y información adicional asociada al nodo (contenida en un objeto $Info$). Representa un punto de inflexión en el tratamiento del paciente, en el cual se modifica la combinación de antirretrovirales a aplicar y la mutante que esta combinación genera. 

\item\textbf{Therapy} es una sucesión de $TherapyNode$s. La cual representa una posible terapia de antirretrovirales, junto con las mutaciones que esta genera.

\item\textbf{TherapyIterator} es una aplicación del pattern $Iterator$, en este caso para iterar sobre una terapia.\\

\end{itemize}


\subsection{Ranker}
Este paquete contiene las clases asociadas al rankeo de terapias y responde a los requerimientos RF7 y RF12.

\begin{figure}[ht]
\centering
\includegraphics[scale=0.7]{pictures/PackageRak.jpeg}
\caption{Paquete Ranker.} 
\end{figure}


\begin{itemize}
\item\textbf{TherapyRanker} hereda de un $Ranker$ genérico y implementa la interfaz $Observer$. Su función es observar las terapias a medida que se generan (RF12) y rankearlas de acuerdo a su puntaje (RF7).

\item\textbf{TherapyScoreComp} es usada por el ranker de terapias para determinar cuales terapias entran en el ranking y cuales no. Su función es tomar dos terapias y decidir cual de las dos es mejor.

\item\textbf{RankingIterator} es una aplicación del pattern $Iterator$ en este caso para iterar sobre el ranking de terapias.
\end{itemize}

%---------------------------------------------------------------------------------------------------------------

\subsection{Generation}
Este paquete contiene todas las clases asociadas a políticas de generación para el árbol de terapias. Responde a los requerimientos RF9.1 y RF5.1.

\begin{figure}[ht]
\centering
\includegraphics[scale=0.7]{pictures/PackageGen.jpeg}
\caption{Paquete Generation.} 
\end{figure}

\begin{itemize}
\item\textbf{GenerationPolicy}provee la interfaz para desarrollar políticas de generación. Las políticas de generación surgen como respuesta al RF5.1. 
La idea detrás de una política de generación es simplificar el algoritmo de generación evitando que el implementador de plugin deba construir objetos complejos y tener un algoritmo, diferente, por tipo de generación. En cambio, se opto por un algoritmo de generación único pero influenciable mediante políticas. (Este punto se explica mejor en el cap. 7)  

Las siguientes clases surgen en respuesta a RF9.1. El funcionamiento de las políticas mencionadas en las últimas tres clases se explican detalladamente en el capitulo 7. 

\item\textbf{Width} hereda de $GenerationPolicy$ y implementa una política similar a BFS (Breadth-first search), se adapta el algoritmo para generar nodos en lugar de buscarlos.

\item\textbf{Depth} hereda de $GenerationPolicy$ y implementa una política similar a DFS (Depth-first search), se adapta el algoritmo para generar nodos en lugar de buscarlos. 

\item\textbf{BetterBeam}también hereda de $GenerationPolicy$ y implementa la política Better Beam, o sea solo toma en consideración los mejores N nodos en cada paso.\\

\end{itemize}

%---------------------------------------------------------------------------------------------------------------

\subsection{Combination}
Este paquete contiene el grupo de clases asociadas a la combinación de antivirales y responden a los requerimientos RF9.2, RF11 y RF12.

\begin{figure}[ht]
\centering
\includegraphics[scale=0.6]{pictures/PackageComb.jpeg}
\caption{Paquete Combination.} 
\end{figure}

\begin{itemize}
\item\textbf{CombinatoryPolicy} provee la interfaz para desarrollar las políticas combinatorias.
 
\item\textbf{CombinationStatus} sirve para indicar al usuario de $CombinatoryPolicy$ el estado en que termino la combinación. Particularmente se usa para indicar el fallo virológico cuando una combinación de antirretrovirales deja de ser efectiva por diversos motivos.

\item\textbf{CombinationObserver} provee la interfaz para observar al algoritmo combinador. 
En un principio se planteo generar todas las combinaciones y luego iterarlas usando el pattern $Iterator$. Con la aparición del RF12 para que el sistema procese información a medida que la genera, se opto por una adaptación del patter $Observer$.\\

Las siguientes clases implementan la interfaz $CombinatoryPolicy$ y se explican más en detalle en el cap. 8.

\item\textbf{EmptyCombinatory} implementa un algoritmo que no genera combinaciones y retorna un $Status$ exitoso, sería el equivalente a SKIP.\\


\item\textbf{NewtonCombinatory} implementa el algoritmo de combinación al estilo newtoneana que retorna como resultado tantas combinaciones como lo indica el coeficiente binomial (todos los subconjuntos de tamaño K de un conjunto de tamaño N).\\


\item\textbf{ListCombinatory} implementa un listador simple itera sobre el conjunto de antirretrovirales y los retorna uno a uno como combinaciones.\\


\item\textbf{SeqCombinatorialGroup} implementa una política de combinación compuesta, que toma un grupo de algoritmos de combinación y las hace combinar de forma secuencial, de manera que un único observador reciba las combinaciones. \\


\item\textbf{ParallelCombinatory} implementa una política compuesta, la cual toma un grupo de algoritmos combinadores y une sus combinaciones a medida que estas se generan. Se entrega al observador la unión de las combinaciones generadas por cada algoritmo que contiene.\\
\end{itemize}

%---------------------------------------------------------------------------------------------------------------

\subsection{Plugin}
Este paquete contiene todas las clases asociadas al concepto de Plugin y de su interacción con el sistema.

\begin{figure}[ht]
\centering
\includegraphics[scale=0.7]{pictures/PackagePl.jpeg}
\caption{Paquete Plugin.} 
\end{figure}

\begin{itemize}
\item\textbf{UserParameter} provee la interfaz para implementar los parámetros que necesite el plugin para funcionar.
 
\item\textbf{GenericParameterImp} implementa la interfaz $UserParameter$ para manipular un argumento genérico (float, string, int, etc.).

Además, el implementador de plugin puede proveer su propia implementación de $UserParameter$ con los chequeos que crea necesarios (RF4.2).\\

Por ejemplo.
\item\textbf{ConditionParameter} generaliza la clase $GenericParameterImp$ para chequear una condición.

\item\textbf{RangeParameter} generaliza la clase $GenericParameterImp$ para chequear que el que el valor este contenido dentro de un rango.

\item\textbf{ParameterList} es básicamente un contenedor que provee un conjunto de métodos para manipularlo.

\item\textbf{Plugin} provee la interfaz para implementar un plugin, con las requerimientos mínimos que usa el sistema (RF5).

\item\textbf{TesisPlugin} implementa la interfaz $Plugin$ y representa el plugin que se distribuye junto con este trabajo el cual se explica en detalle en el cap 10. 

\item\textbf{PluginAdmin} es el encargado de mediar entre el plugin y el sistema, se encarga de chequear la consistencia con el sistema, incorporar el plugin al sistema y removerlo en caso de ser necesario (RF4).
\end{itemize}

%---------------------------------------------------------------------------------------------------------------

\subsection{Therapy Generator}
Este paquete contiene el grupo de clases directamente relacionadas a la generación de terapias (RF6).\\

\begin{figure}[ht]
\centering
\includegraphics[scale=0.7]{pictures/PackageThGe.jpeg}
\caption{Paquete Therapy Generator.} 
\end{figure}

\begin{itemize}

\item\textbf{TherapyGen} provee la interfaz básica de generación de terapias con la que interactua el $MainApp$.

\item\textbf{ChildProcessor} provee una interfaz en la cual se establece como procesar un nodo del árbol y como descartarlo.

\item\textbf{Observer(MutantObs)} provee la interfaz para observar el generador de mutantes(observador de combinaciones).

\item\textbf{TherapyGenImp} esta clase, una de las más complejas del sistema, implementa las interfaces $TherapyGen$, $ChildProcessor$ y $Obsever(MutantObs)$. Su propósito es generar el árbol de terapias a partir de la secuencia inicial y los antirretrovirales de la base de datos.Además, cumple con el RF12 generando el árbol a medida que se observan las mutantes generadas.
El funcionamiento del generador de terapias se explica en detalle en el capítulo 7.2.
\end{itemize}

%---------------------------------------------------------------------------------------------------------------
\subsection{MainApp}
\begin{itemize}
\item\textbf{MainApp} la aplicación principal encargada de obtener y configurar los parámetros de entrada del sistema. Luego invoca a las funciones encargadas de calcular las terapias.
\end{itemize}

\subsection{GUI}
Para que el uso del sistema fuera más orientado a los usuarios finales, se adicionó una interfáz gráfica. La misma está implementada en Qt el cual provee sus propias clases y funcionalidades. Listaremos las más importantes.
\begin{itemize}
\item\textbf{MainWindow} clase que define la aplicación principal. Provee los métodos para crear ventanas y manejarlas en el sistema operativo.
\item\textbf{QMenu} define a un menú con opciones y funcionalidades.
\item\textbf{QString} representación de Qt de una cadena de caracteres.
\item\textbf{QMessageBox} ventana con mensaje de texto para notificar errores, advertencias o información.
\item\textbf{QButton} clase para representar un Botón junto a los eventos que provee.
\item\textbf{QLineEdit} linea de texto editable.
\item\textbf{QLabel} clase para representar un etiqueta.
\item\textbf{QTab} solapas seleccionables.
\item\textbf{QPrinter} clase que provee las funcionalidades de una impresora.
\item\textbf{QTextDocument} clase para definir un documento de texto.
\end{itemize}

%---------------------------------------------------------------------------------------------------------------



